package org.ihelpuoo.weboo.module;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.ihelpuoo.core.Nut;
import org.ihelpuoo.db.ConnectionPool;
import org.ihelpuoo.lang.BooleanUtils;
import org.ihelpuoo.lang.NutException;
import org.ihelpuoo.orm.III;
import org.ihelpuoo.orm.POJO;
import org.ihelpuoo.parser.segment.CharSegment;
import org.ihelpuoo.parser.segment.Segment;
import org.ihelpuoo.parser.segment.SegmentFactory;
import org.ihelpuoo.util.Properties;
import org.ihelpuoo.weboo.util.OutputType;

public final class WebooConfig
{

	//private static Logger	log	= Logger.getLogger(WebooConfig.class);

	public static WebooConfig me(HttpServletRequest request)
	{
		return me(request.getSession().getServletContext());
	}

	public static WebooConfig me(ServletContext sc)
	{
		WebooConfig wc = (WebooConfig)sc.getAttribute(WebooConfig.class.getName());
		if (null == wc)
		{
			synchronized (WebooConfig.class)
			{
				wc = (WebooConfig)sc.getAttribute(WebooConfig.class.getName());
				if (null == wc)
				{
					Nut nut = Nut.me(sc);
					String path = sc.getRealPath("/WEB-INF/weboo/weboo.properties");
					try
					{
						Properties p = nut.getConfig(path);
						Properties.updatePropertiesByServletContext(p,sc);
						wc = new WebooConfig();
						wc.nut = nut;
						wc.init(p);
						wc.setRootPath(sc.getRealPath("/"));
						sc.setAttribute(WebooConfig.class.getName(),wc);
					}
					catch (NutException e)
					{
						throw new RuntimeException(e);
					}
				}
			}
		}
		return wc;
	}

	private WebooConfig()
	{
	}

	private POJO			pojo;

	private Nut				nut;
	private Properties		patternSetting;
	private boolean			isEscapedMessage;
	private DocumentBuilder	dom;
	private String			rootPath;
	private Segment			javaScriptSegment;
	private Segment			cssSegment;
	private String			defaultPatternPrefix;
	private String			contextPath;
	private String			actionSuffix;
	private SegmentFactory	sf;
	private OutputType		actionOutputType;

	public void init(Properties config) throws NutException
	{
		Properties.updatePropertiesByServletContext(config,nut.getHostServletContext());
		III iii = (III)nut.getFactory(config.getStringTrimed("or-mapping"));
		ConnectionPool pool = null;
		if (config.containsKey("pool"))
			pool = (ConnectionPool)nut.getFactory(config.getStringTrimed("pool"));
		pojo = new POJO(nut,iii,pool);
		patternSetting = nut.getConfig(config.getStringTrimed("patterns"));
		javaScriptSegment = new CharSegment(
				"<script language=\"JavaScript\" src=\"${src}\"></script>");
		cssSegment = new CharSegment("<link rel=\"stylesheet\" type=\"text/css\" href=\"${src}\"/>");
		defaultPatternPrefix = config.getStringTrimed("default-pattern-prefix","weboo.pattern.");
		isEscapedMessage = BooleanUtils.parseBoolean(config.getStringTrimed("escaped-message",
				"true"));
		actionOutputType = new OutputType(config.getStringTrimed("action-output","json"));
		actionSuffix = config.getStringTrimed("action-suffix",".o");
		sf = (SegmentFactory)nut.getFactory(config.getStringTrimed("segments"));
		try
		{
			dom = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		}
		catch (ParserConfigurationException e)
		{
			throw new NutException(e);
		}
	}

	public Nut nut()
	{
		return nut;
	}

	public void depose() throws NutException
	{
		nut.depose();
	}

	public SegmentFactory segments()
	{
		return this.sf;
	}

	public void initContextPath(HttpServletRequest request)
	{
		if (null == contextPath)
			contextPath = request.getContextPath();
	}

	public String getContextPath()
	{
		return contextPath;
	}

	public Properties getPatternSetting()
	{
		return patternSetting;
	}

	public Segment getJavaScriptSegment()
	{
		return javaScriptSegment;
	}

	public Segment getCssSegment()
	{
		return cssSegment;
	}

	public String getRootPath()
	{
		return rootPath;
	}

	private void setRootPath(String rootPath)
	{
		this.rootPath = rootPath;
	}

	public String getActionSuffix()
	{
		return actionSuffix;
	}

	public OutputType getActionOutputType()
	{
		return actionOutputType;
	}

	public boolean isEscapedMessage()
	{
		return isEscapedMessage;
	}

	public POJO pojo()
	{
		return pojo;
	}

	public DocumentBuilder dom()
	{
		return dom;
	}

	public String formatPatternName(String name)
	{
		return (name.indexOf('.') == -1 ? defaultPatternPrefix + name : name);
	}

}
